package com.itheima.service.impl;

import com.itheima.mapper.StatisticMapper;
import com.itheima.pojo.MemberCount;
import com.itheima.pojo.SetmealCount;
import com.itheima.service.StatisticService;
import org.apache.poi.xssf.usermodel.XSSFCell;
import org.apache.poi.xssf.usermodel.XSSFRow;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.InputStream;
import java.time.LocalDate;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Service
public class StatisticServiceImpl implements StatisticService {

    @Autowired
    private StatisticMapper statisticMapper;


    //获取会员数量统计数据
    @Override
    public Map<String, Object> getMemberReport() {
        List<MemberCount> memberCounts = statisticMapper.getMemberReport();

        // 提取所有的月份
        List<String> months = memberCounts.stream()
                .map(MemberCount::getMonths)
                .collect(Collectors.toList());

        // 提取所有的会员数量
        List<String> memberCount = memberCounts.stream()
                .map(MemberCount::getMemberCount)
                .collect(Collectors.toList());

        // 构建返回的 Map
        Map<String, Object> map = new HashMap<>();
        map.put("months", months);
        map.put("memberCount", memberCount);
        return map;
    }


    //获取预约套餐占比统计数据
    @Override
    public Map<String, Object> getSetmealReport() {
        List<SetmealCount> setmealCounts = statisticMapper.getSetmealReport();

        // 提取所有的套餐名称
        List<String> setmealNames = setmealCounts.stream()
                .map(SetmealCount::getName)
                .collect(Collectors.toList());

        // 构建返回的 Map
        Map<String, Object> response = new HashMap<>();
        response.put("setmealNames", setmealNames);
        response.put("setmealCount", setmealCounts);

        return response;
    }

    //获取运营统计数据
    @Override
    public Map<String, Object> getBusinessReportData() {
        // 创建返回数据的 Map
        Map<String, Object> reportData = new HashMap<>();

        // 会员数据统计
        int todayNewMember = statisticMapper.getTodayNewMember(); // 今日新增会员数
        int thisWeekNewMember = statisticMapper.getThisWeekNewMember(); // 本周新增会员数
        int thisMonthNewMember = statisticMapper.getThisMonthNewMember(); // 本月新增会员数
        int totalMember = statisticMapper.getTotalMember(); // 总会员数

        //预约到诊数据统计
        int todayOrderNumber = statisticMapper.getTodayOrderNumber(); // 今日预约数
        int thisWeekOrderNumber = statisticMapper.getThisWeekOrderNumber(); // 本周预约数
        int thisMonthOrderNumber = statisticMapper.getThisMonthOrderNumber(); // 本月预约数
        int todayVisitsNumber = statisticMapper.getTodayVisitsNumber(); // 今日到诊数
        int thisWeekVisitsNumber = statisticMapper.getThisWeekVisitsNumber(); // 本周到诊数
        int thisMonthVisitsNumber = statisticMapper.getThisMonthVisitsNumber(); // 本月到诊数

        // 热门套餐数据统计
        List<SetmealCount> setmealReport = statisticMapper.getSetmealReport();
        int totalSetmealCounts = statisticMapper.getTotalSetmealCounts(); // 获取套餐总数量

        List<Map<String, Object>> hotSetmeal = new ArrayList<>();
        for (SetmealCount setmealCount : setmealReport) {
            String setmealName = setmealCount.getName();
            Integer orderCount = setmealCount.getValue();
            double proportion = orderCount * 1.0 / totalSetmealCounts;
            // 创建新的 HashMap 存储当前套餐的数据
            HashMap<String, Object> map = new HashMap<>();
            map.put("name", setmealName);
            map.put("setmeal_count", orderCount);
            map.put("proportion", proportion);
            // 将当前套餐的 HashMap 添加到 List 中
            hotSetmeal.add(map);
        }

        // 封装Map，将各项数据加入到 reportData 中
        reportData.put("todayVisitsNumber", todayVisitsNumber); // 今日到诊数
        reportData.put("reportDate", LocalDate.now().toString()); // 当前日期
        reportData.put("todayNewMember", todayNewMember); // 今日新增会员数
        reportData.put("thisWeekVisitsNumber", thisWeekVisitsNumber); // 本周到诊数
        reportData.put("hotSetmeal", hotSetmeal); // 热门套餐数据
        reportData.put("thisMonthNewMember", thisMonthNewMember); // 本月新增会员数
        reportData.put("thisWeekNewMember", thisWeekNewMember); // 本周新增会员数
        reportData.put("totalMember", totalMember); // 总会员数
        reportData.put("thisMonthOrderNumber", thisMonthOrderNumber); // 本月预约数
        reportData.put("thisMonthVisitsNumber", thisMonthVisitsNumber); // 本月到诊数
        reportData.put("todayOrderNumber", todayOrderNumber); // 今日预约数
        reportData.put("thisWeekOrderNumber", thisWeekOrderNumber); // 本周预约数

        return reportData;
    }


    //导出运营数据到Excel并提供客户端下载
    @Override
    public void exportBusinessReport(HttpServletResponse response) throws IOException {
        // 获取运营数据
        Map<String, Object> reportData = getBusinessReportData();

        // 使用类加载器读取模板文件
        InputStream inputStream = getClass().getClassLoader().getResourceAsStream("templates/report_template.xlsx");

        // 检查模板文件是否存在
        if (inputStream == null) {
            throw new RuntimeException("模板文件未找到！");
        }

        // 基于模板文件创建一个新的Excel文件
        XSSFWorkbook excel = new XSSFWorkbook(inputStream);
        XSSFSheet sheet = excel.getSheetAt(0);// 假设数据填充在第一个工作表中

        // 填充数据到指定单元格
        sheet.getRow(2).getCell(5).setCellValue((String) reportData.get("reportDate"));
        sheet.getRow(4).getCell(5).setCellValue((Integer) reportData.get("todayNewMember"));
        sheet.getRow(4).getCell(7).setCellValue((Integer) reportData.get("totalMember"));
        sheet.getRow(5).getCell(5).setCellValue((Integer) reportData.get("thisWeekNewMember"));
        sheet.getRow(5).getCell(7).setCellValue((Integer) reportData.get("thisMonthNewMember"));
        sheet.getRow(7).getCell(5).setCellValue((Integer) reportData.get("todayOrderNumber"));
        sheet.getRow(7).getCell(7).setCellValue((Integer) reportData.get("todayVisitsNumber"));
        sheet.getRow(8).getCell(5).setCellValue((Integer) reportData.get("thisWeekOrderNumber"));
        sheet.getRow(8).getCell(7).setCellValue((Integer) reportData.get("thisWeekVisitsNumber"));
        sheet.getRow(9).getCell(5).setCellValue((Integer) reportData.get("thisMonthOrderNumber"));
        sheet.getRow(9).getCell(7).setCellValue((Integer) reportData.get("thisMonthVisitsNumber"));


        List<Map<String, Object>> hotSetmeal = (List<Map<String, Object>>) reportData.get("hotSetmeal");
        int i = 12; // 初始化行数，从第12行开始
        for (Map<String, Object> map : hotSetmeal) {
            // 判断第 i 行是否存在
            XSSFRow row = sheet.getRow(i);
            if (row == null) {
                row = sheet.createRow(i); // 如果行不存在，则创建
            }

            // 判断第 i 行的第 4 到 7 个单元格是否存在
            for (int j = 4; j <= 7; j++) {
                XSSFCell cell = row.getCell(j);
                if (cell == null) {
                    row.createCell(j); // 如果单元格不存在，则创建
                }
            }

            // 依次填充套餐名称、预约数量和比例到 Excel 的相应单元格
            sheet.getRow(i).getCell(4).setCellValue((String) map.get("name"));
            sheet.getRow(i).getCell(5).setCellValue((Integer) map.get("setmeal_count"));
            sheet.getRow(i).getCell(6).setCellValue((Double) map.get("proportion"));
            i++; // 递增行号，准备写入下一行
        }

        // 设置响应头
        response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
        response.setHeader("Content-Disposition", "attachment; filename=report.xlsx");

        //通过输出流将Excel文件下载到客户端浏览器
        ServletOutputStream outputStream = response.getOutputStream();
        excel.write(outputStream);

        // 关闭资源
        outputStream.close();
        excel.close();
    }


}
